home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / quake.zip / PERFEC_1.ZIP / HOOK.QC < prev    next >
Text File  |  1997-04-19  |  11KB  |  338 lines

  1. //====================================================================
  2. //
  3. // BASED ON: HOOK 2.2 & 3.0b3    by: Perecli Manole AKA Bort
  4. //
  5. // MODIFIED BY: Enrico Del Fante (TbEnr)
  6. //
  7. //====================================================================
  8. // Aside from this new file, the following are the modifications
  9. // done to id's original source files:
  10. //--------------------------------------------------------------------
  11. // File: Progs.src
  12. // Location: before the "weapons.qc" line
  13. // Added: hook.qc
  14. //--------------------------------------------------------------------
  15. // File: World.qc
  16. // Procedure: worldspawn
  17. // Location: after line "precache_model ("progs/s_spike.mdl");"
  18. // Added: precache_model ("progs/star.mdl");
  19. //        precache_model ("progs/bit.mdl");
  20. //--------------------------------------------------------------------
  21. // File: Weapons.qc
  22. // Procedure: W_Precache
  23. // Location: end of procedure
  24. // Added: precache_sound ("shambler/smack.wav");
  25. //        precache_sound ("blob/land1.wav");
  26. //      precache_sound ("hook/retract.wav");
  27. //--------------------------------------------------------------------
  28. // File: Weapons.qc
  29. // Procedure: W_WeaponFrame
  30. // Location: in the begining of procedure
  31. // Added: CheckGrapHook ();
  32. //--------------------------------------------------------------------
  33. // File: Weapons.qc
  34. // Procedure: W_WeaponFrame
  35. // Location: after line "if (time < self.attack_finished)" before 
  36. //           line "return;"
  37. // Added: {
  38. //        self.impulse=0;
  39. //        (leave line "return;")
  40. //       }
  41. //--------------------------------------------------------------------
  42. // File: Defs.qc
  43. // Declaration group: player only fields
  44. // Location: after line ".float pain_finished;"
  45. // Added: .float hook;    
  46. //--------------------------------------------------------------------
  47.  
  48. void(vector org, vector vel, float damage) SpawnBlood;    // prototype
  49. float () crandom;                               // prototype
  50.  
  51.  
  52. float    HOOK_OUT = 1;        // is hook currently extended? (bit flag)
  53. float    HOOK_ON = 2;        // is ACTIVE_HOOK impulse on? (bit flag)
  54. float   HOOK_PULL = 4;
  55. float   HOOK_CANC = 8;
  56. float   ACTIVATE_HOOK = 98;     // impulse constant
  57. float    TERMINATE_HOOK = 97;    // impulse constant
  58. float MAX_CHAIN_LEN = 800;
  59.  
  60. float (vector from, vector onto) Dot =
  61. {
  62.         return from_x * onto_x + from_y * onto_y + from_z * onto_z;
  63.         };
  64. /*
  65. //--------------------------------------------------------------------
  66.   // Disolves chain
  67. //--------------------------------------------------------------------
  68. void (entity Head) DisolveChain =
  69. {
  70.     local entity link;
  71.  
  72.     link = Head.goalentity;
  73.     while (link != world)
  74.     {
  75.         Head = link.goalentity;
  76.         remove (link);
  77.         link = Head;
  78.     }
  79. };
  80. */
  81. //--------------------------------------------------------------------
  82. // Updated calculation of link positions
  83. //--------------------------------------------------------------------
  84. void () LinkPos =
  85. {
  86.     setorigin (self, self.owner.origin + ((self.enemy.origin + '0 0 16') - self.owner.origin) * self.weapon);
  87.     self.nextthink = time + 0.01;
  88. };
  89.  
  90.  
  91. //--------------------------------------------------------------------
  92. // Creates chain
  93. //--------------------------------------------------------------------
  94. entity (entity head, entity tail, float num) CreateChain =
  95. {
  96.     local entity link, prevlink;
  97.     local float linknum;
  98.  
  99.     linknum = num;
  100.     num = num + 1;
  101.     prevlink = world;
  102.     while (linknum > 0)
  103.     {
  104.         link = spawn();
  105.         link.goalentity = prevlink;
  106.         prevlink = link;
  107.         link.owner = head;
  108.         link.enemy = tail;
  109.         link.weapon = linknum / num;
  110.         link.movetype = MOVETYPE_NOCLIP;
  111.         link.solid = SOLID_NOT;
  112.         link.angles_z = 51 * linknum;
  113.         link.angles_y = 41 * linknum;
  114.         link.angles_x = 31 * linknum;
  115.         link.avelocity = '310 410 510';
  116.         setmodel (link, "progs/bit.mdl");
  117.         setsize (link, '0 0 0', '0 0 0');
  118.         setorigin (link, head.origin + ((tail.origin + '0 0 16') - head.origin) * link.weapon);
  119.         link.nextthink = time + 0.01;
  120.         link.think = LinkPos;
  121.         linknum = linknum - 1;
  122.     }
  123.     return link;
  124. };
  125.  
  126.  
  127. //--------------------------------------------------------------------
  128. // Removes star and detaches player
  129. //--------------------------------------------------------------------
  130. void () HookVanish =
  131. {
  132.     // removes flag of hook instance being present
  133.     self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_OUT);
  134.     self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_CANC);
  135.     self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_PULL);
  136.         local entity linkptr;
  137.         local entity nextptr;
  138.  
  139.          // removes chain
  140.           linkptr = self.goalentity;
  141.           while (linkptr != world)
  142.           {
  143.             nextptr = linkptr.goalentity;
  144.               remove (linkptr);
  145.                 linkptr = nextptr;
  146.           }
  147.     sound (self.owner, CHAN_AUTO, "hook/retract.wav", 1, ATTN_NORM);
  148.  remove (self);
  149. };
  150.  
  151. //--------------------------------------------------------------------
  152. // Hook pulls player function
  153. //--------------------------------------------------------------------
  154. void () HookPull =
  155. {
  156.         if ((self.owner.hook & HOOK_CANC) == HOOK_CANC)
  157.     {
  158.         HookVanish();
  159.         return;
  160.     }
  161.     local vector vel, spray, velpart;
  162.         local float v,f1,i1,i2;
  163.         local vector chainvec;                   // chain vector        
  164.         local float chainlength;                        // length of extended chain
  165.  
  166.         if ((self.owner.teleport_time > time) || 
  167.         (self.owner.deadflag) ||            // if player dies
  168.         (self.enemy.solid == SOLID_NOT)    )    // if target dies
  169.     {
  170.         HookVanish();
  171.         return;
  172.     }
  173.     
  174.     if (self.enemy.takedamage)
  175.         T_Damage (self.enemy, self, self.owner, 3);
  176.  
  177.     if (self.enemy.solid == SOLID_SLIDEBOX)
  178.     {
  179.         sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
  180.         spray_x = 100 * crandom();
  181.          spray_y = 100 * crandom();
  182.         spray_z = 100 * crandom() + 50;
  183.         SpawnBlood (self.origin, spray, 20);
  184.         setorigin (self, self.enemy.origin + self.enemy.mins + self.enemy.size * 0.5);
  185.     }
  186.  
  187.     self.velocity = self.enemy.velocity;
  188.     
  189.   chainvec = self.origin - (self.owner.origin + '0 0 16');
  190.   chainlength = vlen (chainvec);
  191.  
  192. if ((self.owner.hook & HOOK_ON) == HOOK_ON) {
  193.         vel = self.origin - (self.owner.origin + '0 0 16');
  194.     v = vlen (vel);
  195.     if (v <= 100)
  196.         vel = normalize(vel) * v * 7;  
  197.     if ( v > 100 )
  198.         vel = normalize(vel) * 700;  
  199.     self.owner.velocity = vel;
  200.         self.armorvalue=chainlength;
  201. }
  202. else
  203. {
  204.    if (chainlength > self.armorvalue)
  205.        {
  206.       f1 = (chainlength - self.armorvalue) * 3;
  207.        // dampens player's velocity moving away from hook
  208.      i1 = Dot(self.owner.velocity,chainvec);
  209.     i2 = Dot(chainvec,chainvec);
  210.   velpart = chainvec * (i1 / i2);
  211.    self.owner.velocity = self.owner.velocity - velpart;
  212.   i1 = vlen (velpart);
  213.      if (i1 > 600)
  214.        sound (self.owner, CHAN_AUTO, "player/land2.wav", 1, ATTN_NORM);
  215. }
  216. else
  217. f1 = 0;
  218.         // applys forces to players velocity
  219.  self.owner.velocity = self.owner.velocity + normalize(chainvec) * f1;
  220.  
  221. }
  222. self.nextthink = time + 0.1;
  223. };
  224.  
  225.  
  226. //--------------------------------------------------------------------
  227. // Star's touch function
  228. //--------------------------------------------------------------------
  229. void() T_ChainTouch =
  230. {
  231.     if (other.takedamage) 
  232.         T_Damage (other, self, self.owner, 10 );
  233.  
  234.      if (other.solid == SOLID_SLIDEBOX)
  235.     {
  236.         sound (self, CHAN_WEAPON, "shambler/smack.wav", 1, ATTN_NORM);    
  237.         SpawnBlood (self.origin, self.velocity, 10);
  238.         setorigin (self, other.origin + other.mins + other.size * 0.5);
  239.     }
  240.     else
  241.     {
  242.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  243.         self.avelocity = '0 0 0';
  244.     }
  245.  
  246.     self.velocity = other.velocity;
  247.     
  248.         if ((self.owner.hook & HOOK_ON) == HOOK_ON)
  249.            self.owner.hook=self.owner.hook | HOOK_PULL;
  250.         else self.owner.hook=self.owner.hook - (self.owner.hook & HOOK_PULL);
  251.  
  252.     self.enemy = other;
  253.     self.nextthink = time + 0.1;
  254.     self.think = HookPull;
  255.     self.touch = SUB_Null;
  256. };
  257.  
  258. void() LaunchHook =
  259. {
  260.       local vector chainvec;                            // chain vector
  261.         local float chainlength;                        // length of extended chain
  262.  
  263.         chainvec = self.origin - (self.owner.origin + '0 0 16');
  264.         chainlength = vlen (chainvec);
  265.  
  266.        // armorvalue is used to hold current length of chain
  267.        self.armorvalue = chainlength;
  268.  
  269.        if (chainlength > MAX_CHAIN_LEN)
  270.        {
  271.                              HookVanish();
  272.                              return;
  273.                          }
  274.        self.nextthink = time + 0.1;
  275. };
  276.  
  277.  
  278. //--------------------------------------------------------------------
  279. // Shoots star
  280. //--------------------------------------------------------------------
  281. void(entity myself) W_FireChain =
  282. {
  283.     local entity star;
  284.  
  285.     star = spawn ();
  286.     star.owner = myself;
  287.     star.movetype = MOVETYPE_FLY;
  288.     star.solid = SOLID_BBOX;
  289.     setmodel (star, "progs/star.mdl");
  290.     setsize (star, '0 0 0', '0 0 0');     
  291.     makevectors (myself.v_angle);
  292.     setorigin (star, myself.origin + (v_forward*16) + '0 0 16' );
  293.     star.velocity = v_forward*1000;
  294.     star.angles = vectoangles(star.velocity);
  295.     star.avelocity = '0 0 600';
  296.     sound (myself, CHAN_AUTO, "weapons/ax1.wav", 1, ATTN_NORM);
  297.     
  298.     star.touch = T_ChainTouch;
  299.         star.nextthink = time + 0.1; 
  300.         star.think = LaunchHook;
  301.     star.goalentity = CreateChain (star, myself, 8);
  302. };
  303.  
  304.  
  305. //--------------------------------------------------------------------
  306. // Checks impulse
  307. //--------------------------------------------------------------------
  308. void() CheckGrapHook = 
  309. {
  310.         if (((self.hook & HOOK_OUT) != HOOK_OUT) && (self.impulse == ACTIVATE_HOOK))
  311.     {
  312.         // flags that one instance of hook is spawned
  313.         self.hook = self.hook | HOOK_OUT;
  314.     
  315.         // flags last activated hook impulse as being ON 
  316.         self.hook = self.hook | HOOK_ON;   
  317.  
  318.         W_FireChain (self);
  319.         return;
  320.     }
  321.         if (((self.hook & HOOK_ON) != HOOK_ON) && (self.impulse == ACTIVATE_HOOK))
  322.         {
  323.                 if (((self.hook & HOOK_OUT) == HOOK_OUT) && ((self.hook & HOOK_PULL) != HOOK_PULL))
  324.             self.hook=self.hook | HOOK_CANC;
  325.         self.hook = self.hook | HOOK_ON;
  326.         return;
  327.         }
  328.     if (((self.hook & HOOK_OUT) == HOOK_OUT) && (self.impulse == TERMINATE_HOOK))
  329.     {
  330.         if ((self.hook & HOOK_PULL) == HOOK_PULL) 
  331.             self.hook = self.hook | HOOK_CANC;
  332.         // flags last activated hook impulse as being OFF
  333.         self.hook = self.hook - (self.hook & HOOK_ON);
  334.         return;
  335.     }
  336.  
  337. }; 
  338.